package vip.aster.system.controller;

import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.servlet.http.HttpServletRequest;
import lombok.AllArgsConstructor;
import org.springframework.web.bind.annotation.*;
import vip.aster.common.constant.enums.MenuTypeEnum;
import vip.aster.common.exception.BusinessException;
import vip.aster.common.utils.ResultInfo;
import vip.aster.framework.i18n.MessageUtils;
import vip.aster.framework.log.annotation.Log;
import vip.aster.framework.log.enums.BusinessTypeEnum;
import vip.aster.framework.security.entity.SecurityUser;
import vip.aster.framework.security.utils.TokenUtils;
import vip.aster.system.service.SysAuthService;
import vip.aster.system.service.SysCaptchaService;
import vip.aster.system.service.SysMenuService;
import vip.aster.system.service.SysTenantService;
import vip.aster.system.vo.*;
import vip.aster.tenant.utils.TenantUtils;

import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 认证管理
 *
 * @author Aster
 * @since 2023/11/30 10:45
 */
@Tag(name = "认证管理")
@RestController
@RequestMapping("/sys/auth")
@AllArgsConstructor
public class SysAuthController {
    private SysCaptchaService sysCaptchaService;
    private SysAuthService sysAuthService;
    private SysMenuService sysMenuService;
    private SysTenantService sysTenantService;

    @GetMapping("/captcha")
    @Operation(summary = "验证码")
    public ResultInfo<SysCaptchaVO> captcha() {
        SysCaptchaVO captchaVO = sysCaptchaService.generate();
        return ResultInfo.success(captchaVO);
    }

    @GetMapping("/captcha/enabled")
    @Operation(summary = "是否开启验证码")
    public ResultInfo<Boolean> captchaEnabled() {
        boolean enabled = sysCaptchaService.isCaptchaEnabled();
        return ResultInfo.success(enabled);
    }

    @GetMapping("/tenant/enabled")
    @Operation(summary = "是否开启租户")
    public ResultInfo<Boolean> tenantEnabled() {
        return ResultInfo.success(TenantUtils.isEnable());
    }

    @GetMapping("/tenant")
    @Operation(summary = "租户列表")
    public ResultInfo<List<SysTenantVO>> tenantList() {
        List<SysTenantVO> list = sysTenantService.getList();
        return ResultInfo.success(list);
    }

    @GetMapping("/secretKey")
    @Operation(summary = "获取公钥")
    public ResultInfo<String> secretKey() {
        String key = "";
        try {
            key = sysAuthService.generateSecretKey();
        } catch (NoSuchAlgorithmException e) {
            throw new BusinessException(MessageUtils.message("auth.secret.key.error"));
        }
        return ResultInfo.success(key);
    }

    @PostMapping("/login")
    @Operation(summary = "账号密码登录")
    public ResultInfo<SysTokenVO> login(@RequestBody SysAccountLoginVO login) {
        SysTokenVO token = sysAuthService.loginByAccount(login);
        return ResultInfo.success(token);
    }

    @PostMapping("/send/code")
    @Operation(summary = "发送短信验证码")
    public ResultInfo<String> sendCode(String mobile) {
        boolean flag = sysAuthService.sendCode(mobile);
        if (!flag) {
            return ResultInfo.failed(MessageUtils.message("auth.send.code.error"));
        }

        return ResultInfo.success();
    }

    @PostMapping("/mobile")
    @Operation(summary = "手机号登录")
    public ResultInfo<SysTokenVO> mobile(@RequestBody SysMobileLoginVO login) {
        SysTokenVO token = sysAuthService.loginByMobile(login);

        return ResultInfo.success(token);
    }

    @PostMapping("/logout")
    @Operation(summary = "退出")
    @Log(type = BusinessTypeEnum.CLEAN)
    public ResultInfo<String> logout(HttpServletRequest request) {
        sysAuthService.logout(TokenUtils.getAccessToken(request));

        return ResultInfo.success();
    }

    @PostMapping("/resetPassword")
    @Operation(summary = "重置密码")
    @Log(type = BusinessTypeEnum.UPDATE)
    public ResultInfo<String> resetPassword(@RequestBody List<String> idList) {
        sysAuthService.resetPassword(idList);

        return ResultInfo.success();
    }

    @GetMapping("/menu")
    @Operation(summary = "菜单权限")
    @Log(type = BusinessTypeEnum.SEARCH)
    public ResultInfo<List<SysMenuVO>> menu() {
        List<String> types = new ArrayList<>();
        types.add(MenuTypeEnum.DIRECTORY.getCode());
        types.add(MenuTypeEnum.MENU.getCode());
        List<SysMenuVO> menuList = sysMenuService.getUserMenuList(SecurityUser.getUser(), types);
        return ResultInfo.success(menuList);
    }

    @GetMapping("/authority")
    @Operation(summary = "按钮权限")
    @Log(type = BusinessTypeEnum.SEARCH)
    public ResultInfo<Set<String>> authority() {
        Set<String> authority = sysMenuService.getUserAuthority(SecurityUser.getUser());
        return ResultInfo.success(authority);
    }
}
